home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / IFC_112 / netscape / application / TargetChain.java < prev    next >
Encoding:
Text File  |  1999-05-28  |  9.6 KB  |  259 lines  |  [TEXT/CWIE]

  1. // TargetChain.java
  2. // By Ned Etcode
  3. // Copyright 1995, 1996, 1997 Netscape Communications Corp. All rights reserved.
  4.  
  5.  
  6. package netscape.application;
  7. import netscape.util.*;
  8.  
  9. /** Object subclass used to locate a Target within an application that is
  10.   * capable of performing a specific command.  When asked to perform a command,
  11.   * the TargetChain asks each of its potential Targets, in turn, whether or
  12.   * not they implement the ExtendedTarget interface, and if so, calls their
  13.   * <b>canPerformCommand()</b> method to determine whether or not they can
  14.   * perform the specified command.  The TargetChain forwards the command on
  15.   * to the first object that can perform the command.  The TargetChain
  16.   * returned by the static <b>applicationChain()</b> method contains the
  17.   * following potential Targets:
  18.   * <UL>
  19.   * <LI>Each of the targets added using addTarget with atFront == true</LI>
  20.   * <LI>firstRootView's focused view </LI>
  21.   * <LI>if there is a document window </LI>
  22.   * <UL>
  23.   * <LI>document window's focused view if different from firstRootView's focused
  24.   * view</LI>
  25.   * <LI>document window's owner</LI>
  26.   * <LI>document window </LI>
  27.   * </UL>
  28.   * <LI>else if firstRootView not equal to mainRootView </LI>
  29.   * <UL>
  30.   * <LI>mainRootView's focused view </LI>
  31.   * </UL>
  32.   * <LI>firstRootView's window's owner</LI>
  33.   * <LI>firstRootView's window</LI>
  34.   * <LI>firstRootView</LI>
  35.   * <LI>application</LI>
  36.   * <LI>Each of the targets added using addTarget with atFront == false </LI>
  37.   * </UL>
  38.   * When a window is modal, the target chain changes so a component outside of
  39.   * the modal loop cannot receive a command.
  40.   * The TargetChain is useful in situations where the Target that should
  41.   * receive a command is context sensitive.  For example, a Menu item
  42.   * representing the "cut" command should send its command to the current
  43.   * selection.  If an application has multiple TextFields, the TextField that
  44.   * should receive the command will depend upon which TextField the user has
  45.   * decided to edit.  By setting the Menu item's Target to the application's
  46.   * TargetChain, the application can configure the Menu item's Target once,
  47.   * with the assurance that the TargetChain will locate and forward the command
  48.   * to the appropriate object.
  49.   * @see Target
  50.   * @note 1.0 changes for focus model and keyboard UI
  51.   */
  52.  
  53. public class TargetChain implements ExtendedTarget {
  54.     private Vector preTargets = new Vector();
  55.     private Vector postTargets = new Vector();
  56.     private static TargetChain applicationChain;
  57.  
  58.     private TargetChain() {
  59.         super();
  60.     }
  61.  
  62.     /** Returns the Application global TargetChain.
  63.         */
  64.     public static TargetChain applicationChain() {
  65.         if (applicationChain == null) {
  66.             applicationChain = new TargetChain();
  67.         }
  68.         return applicationChain;
  69.     }
  70.  
  71.     /** Adds <b>target</b> to the TargetChain. If <b>atFront</b> is
  72.       * <b>true</b>,the TargetChain will query <b>target</b> before any of the
  73.       * ExtendedTargets currently in its list. Otherwise, the TargetChain will
  74.       * query <b>target</b> only after all current ExtendedTargets.
  75.       */
  76.     public synchronized void addTarget(ExtendedTarget target,
  77.                                        boolean atFront) {
  78.         if (atFront) {
  79.             preTargets.insertElementAt(target, 0);
  80.         } else {
  81.             postTargets.addElement(target);
  82.         }
  83.     }
  84.  
  85.     /** Removes <b>target</b> from the TargetChain (only if <b>target</b> was
  86.       * added using <b>addTarget()</b>).
  87.       * @see #addTarget
  88.       */
  89.     public synchronized void removeTarget(ExtendedTarget target) {
  90.         preTargets.removeElement(target);
  91.         postTargets.removeElement(target);
  92.     }
  93.  
  94.     /** Returns the first Target that performs <B>command</B>.
  95.       */
  96.     public synchronized Target targetForCommand(String command) {
  97.         int             i, size;
  98.         Application     app;
  99.         View            focusedView;
  100.         RootView        firstRootView,mainRootView;
  101.         Window          documentWindow, firstWindow;
  102.         WindowOwner     documentOwner, firstOwner;
  103.  
  104.         View modalView;
  105.  
  106.         /* Target added with atFront == true */
  107.         size = preTargets.size();
  108.         for (i = 0; i < size; i++) {
  109.             ExtendedTarget target = (ExtendedTarget) preTargets.elementAt(i);
  110.  
  111.             if (target.canPerformCommand(command)) {
  112.                 return target;
  113.             }
  114.         }
  115.  
  116.         app = Application.application();
  117.  
  118.         /** Modal session going on? */
  119.         modalView = app.modalView();
  120.  
  121.         if(modalView == null) {
  122.             /* First root view's focused view */
  123.  
  124.             firstRootView = app.firstRootView();
  125.             if (firstRootView != null) {
  126.                 focusedView = firstRootView.focusedView();
  127.                 if (objectCanPerformCommand(focusedView,command))
  128.                     return (Target)focusedView;
  129.             }
  130.  
  131.             /* Document window */
  132.             documentWindow = app.currentDocumentWindow();
  133.             if(documentWindow != null) {
  134.  
  135.                 /* Document window focused view ? */
  136.                 if(documentWindow instanceof InternalWindow)
  137.                     focusedView = ((InternalWindow)documentWindow).focusedView();
  138.                 else
  139.                     focusedView = ((ExternalWindow)documentWindow).rootView().focusedView();
  140.                 if(objectCanPerformCommand(focusedView,command))
  141.                     return (Target)focusedView;
  142.  
  143.                 /* Document window owner ?*/
  144.                 documentOwner = documentWindow.owner();
  145.                 if(objectCanPerformCommand(documentOwner,command))
  146.                     return (Target)documentOwner;
  147.  
  148.                 /* Document window ? */
  149.                 if(objectCanPerformCommand(documentWindow,command))
  150.                     return (Target)documentWindow;
  151.             } else if((mainRootView = (app.mainRootView())) != null)    {
  152.                 if(mainRootView.mainWindow() == null) {
  153.                     /* mainRootView's focusedview ? */
  154.                     focusedView = mainRootView.focusedView();
  155.                 } else  {
  156.                     focusedView = mainRootView.rootViewFocusedView();
  157.                 }
  158.                 if(objectCanPerformCommand(focusedView,command))
  159.                     return (Target)focusedView;
  160.             }
  161.  
  162.             if(firstRootView != null) {
  163.                 /* firstRootView's window owner */
  164.                 firstWindow = firstRootView.externalWindow();
  165.                 if(firstWindow != null) {
  166.                     firstOwner = firstWindow.owner();
  167.                     if(objectCanPerformCommand(firstOwner,command))
  168.                         return (Target)firstOwner;
  169.  
  170.                     /* firstWindow? */
  171.                     if(objectCanPerformCommand(firstWindow,command))
  172.                         return (Target)firstWindow;
  173.                 }
  174.  
  175.                 /* firstRootView? */
  176.                 if(objectCanPerformCommand(firstRootView,command))
  177.                     return (Target) firstRootView;
  178.             }
  179.  
  180.             /** Application? **/
  181.             if(objectCanPerformCommand(app,command))
  182.                 return (Target) app;
  183.         } else { /* Modal view not null */
  184.             if(modalView instanceof RootView) { /* External Window modal */
  185.                 firstRootView = (RootView) modalView;
  186.                 focusedView = firstRootView.focusedView();
  187.                 firstWindow = firstRootView.externalWindow();
  188.             } else if(modalView instanceof InternalWindow) {/* Internal Window modal */
  189.                 firstRootView = null;
  190.                 focusedView = ((InternalWindow)modalView).focusedView();
  191.                 firstWindow = (Window) modalView;
  192.             } else { /* Random modal view */
  193.                 firstRootView = null;
  194.                 focusedView = modalView;
  195.                 firstWindow = null;
  196.             }
  197.  
  198.             /* Focused view? */
  199.             if(objectCanPerformCommand(focusedView,command))
  200.                 return (Target)focusedView;
  201.  
  202.             if(firstWindow != null) {
  203.                 firstOwner = firstWindow.owner();
  204.                 /* Window owner?  */
  205.                 if(objectCanPerformCommand(firstOwner,command))
  206.                     return (Target)firstOwner;
  207.                 /* Window? */
  208.                 if(objectCanPerformCommand(firstWindow,command))
  209.                     return (Target)firstWindow;
  210.             }
  211.  
  212.             /* firstRootView? */
  213.             if(firstRootView != null) {
  214.                 if(objectCanPerformCommand(firstRootView,command))
  215.                     return (Target)firstRootView;
  216.             }
  217.         }
  218.  
  219.         /* Target added with atFront == true */
  220.         size = postTargets.size();
  221.         for (i = 0; i < size; i++) {
  222.             ExtendedTarget target = (ExtendedTarget) postTargets.elementAt(i);
  223.  
  224.             if (target.canPerformCommand(command)) {
  225.                 return target;
  226.             }
  227.         }
  228.  
  229.         return null;
  230.     }
  231.  
  232.     /** Returns <b>true</b> if any of the TargetChain's Targets can perform
  233.       * <B>command</B>.
  234.       */
  235.     public boolean canPerformCommand(String command) {
  236.         return (targetForCommand(command) != null);
  237.     }
  238.  
  239.     /** Forwards the performCommand message to the first Target in the chain
  240.       * that can perform <B>command</B>.
  241.       */
  242.     public void performCommand(String command, Object data) {
  243.         Target target = targetForCommand(command);
  244.  
  245.         if (target != null) {
  246.             target.performCommand(command, data);
  247.         }
  248.     }
  249.  
  250.     private boolean objectCanPerformCommand(Object anObject,String command) {
  251.         if( anObject != null &&
  252.            (anObject instanceof ExtendedTarget) &&
  253.             ((ExtendedTarget)anObject).canPerformCommand(command))
  254.             return true;
  255.         else
  256.             return false;
  257.     }
  258. }
  259.